package nlp;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

import org.tartarus.snowball.ext.porterStemmer;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.CompactWriter;

import edu.stanford.nlp.tagger.maxent.MaxentTagger;

public class TextDocument implements Document {
	private TextDocumentData internalData;
	public static MaxentTagger tagger;
	public static HashSet<String> stopWordSet;
	public static HashSet<String> moodWordSet;
	public static HashMap<String, Double> tfiafMap;
	public static HashMap<String, Double> tfiaftpfMap;

	// Create all feature for this text document.
	private void CreateFeatures() {
		String textString = internalData.getTextString();
		porterStemmer stemmer = new porterStemmer();
		List<FeatureCreator> featCreators = new ArrayList<FeatureCreator>();
		featCreators.add(new NGramFeatureCreator(textString, stemmer));
		featCreators.add(new POSGramFeatureCreator(textString,
				TextDocument.tagger));
		featCreators.add(new StopwordsFeatureCreator(textString, stemmer,
				TextDocument.stopWordSet));
		featCreators.add(new MoodwordsFeatureCreator(textString, stemmer,
				TextDocument.moodWordSet));
		featCreators.add(new TfIafFeatureCreator(textString, stemmer,
				TextDocument.tfiafMap));
		featCreators.add(new TfIafTpfFeatureCreator(textString, stemmer,
				TextDocument.tfiaftpfMap));

		for (FeatureCreator featCreator : featCreators) {
			System.err.println("Creating: " + featCreator.GetFeatureName());
			featCreator.CreateFeature(internalData.getFeatureMap());
		}
	}

	// Constructor.
	public TextDocument() {
	}

	public TextDocument(String textString, String label) {
		this.internalData = new TextDocumentData(textString,
				new HashMap<String, Feature>(), label);

		// Initiate feature creation.
		CreateFeatures();
	}

	@Override
	public String[] GetAllFeatureNames() {
		HashMap<String, Feature> featureMap = internalData.getFeatureMap();
		String[] featureNames = new String[featureMap.size()];
		int i = 0;
		for (String name : featureMap.keySet()) {
			featureNames[i++] = name;
		}
		Arrays.sort(featureNames);
		return featureNames;
	}

	@Override
	public Feature GetFeature(String name) {
		if (!internalData.getFeatureMap().containsKey(name)) {
			return null;
		}
		return internalData.getFeatureMap().get(name);
	}

	@Override
	public String GetLabel() {
		return internalData.getLabel();
	}

	@SuppressWarnings("unchecked")
	@Override
	public void Deserialize(String featureString) {
		XStream xstream = new XStream();
		this.internalData = (TextDocumentData) xstream.fromXML(featureString);
	}

	@Override
	public String SerializeFeatures() {
		this.internalData.setTextString("");
		XStream xstream = new XStream();
		StringWriter sw = new StringWriter();
		xstream.marshal(this.internalData, new CompactWriter(sw));
		return sw.toString();
	}
}
